import os
from typing import Annotated
from sqlalchemy.orm import Session
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from passlib.context import CryptContext
from jose import jwt, JWTError
from dotenv import load_dotenv
from pydantic import BaseModel
from api.database import SessionLocal

load_dotenv()

SECRET_KEY = os.getenv("AUTH_SECRET_KEY")
ALGORITHM = os.getenv("AUTH_ALGORITHM")

def get_db():
    # 生成一个新的 SQLAlchemy Session
    db = SessionLocal()
    try:
        # 将 Session 提供给路由使用
        yield db
    finally:
        # 在请求完成后自动关闭它
        db.close()

# db_dependency 是 FastAPI 依赖注入系统的一个快捷方式，用于在路由中获取 SQLAlchemy Session
# 它的本质是通过 get_db() 生成一个临时 Session，并在请求结束时自动清理
# Annotated[Session, Depends(get_db)] 表示这是一个依赖项，类型是 SQLAlchemy 的 Session
#    Depends(get_db) 表示 FastAPI 会调用 get_db() 函数来获取数据库会话（Session）
db_dependency = Annotated[Session, Depends(get_db)]

bcrypt_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
# 在 Swagger UI 或 ReDoc 中，tokenUrl 会显示一个 "Authorize"按钮，点击后引导用户到指定的登录页面（这里是 /auth/token）
# 即使 tokenUrl 填错（如 tokenUrl="not-exist"），也不会影响代码运行，只会让文档的引导链接失效。
# OAuth2PasswordBearer 的设计就是提取并返回 Token 字符串
oauth2_bearer = OAuth2PasswordBearer(tokenUrl="auth/token")
# 自动提取请求头中的 Token（str）
# 执行流程：
# 当你在路由中使用 oauth2_bearer_dependency（即 Depends(oauth2_bearer)）时：
# FastAPI 会调用 oauth2_bearer()（即 OAuth2PasswordBearer.__call__）。
# 该方法会检查请求的 Authorization 头部，验证格式是否为 Bearer <token>。
# 如果有效，返回 <token>（str 类型）；否则抛出 HTTP 401 错误。
oauth2_bearer_dependency = Annotated[str, Depends(oauth2_bearer)]

class CurrentUser(BaseModel):
    username: str
    id: int

async def get_current_user(token: oauth2_bearer_dependency) -> CurrentUser:
    """根据token解析user"""
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username = payload.get("sub")
        user_id = payload.get("id")
        if username is None or user_id is None:
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate user")
        return CurrentUser(username=username, id=user_id)
    except JWTError:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate user")

# 自动根据token获取当前已登陆用户的用户名和id
user_dependency = Annotated[dict, Depends(get_current_user)]